package dyyx.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.StringUtils;



public abstract class CommUtil{
	
	public static final AtomicLong initOrder = new AtomicLong(0);

	
	public static final String VERSION = "2018-07-20 14:39";

	private static final String UTF8 = "utf8";
	private static final String CONF = "/conf.properties";

	public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
	
	public static final String DATE_FORMAT_NO_TIME = "yyyy-MM-dd";

	
	public static final String PV_TIME_FORMAT = "yyyy-MM-dd HH";


    public static final String YES = "Y";
    public static final String NO = "N";
    
   
    private static final int YEAR_OFFSET = 1900;
    private static final int MONTH_OFFSET = 1;

    private static final String LINK = "-";
    private static final String TIME_SEP = ":";

    
    private static final String SEP = ",";
    private static final String EQ = "=";


    private static Map<String,String> configMap = null;

	static {

		try {
			Map<String, String> maptmp = getConfigMap_();
			if (maptmp == null) {
				maptmp = new HashMap<String, String>();
			}
			configMap = maptmp;
		} catch (Throwable e) {
			throw new RuntimeException("getConfMap error");
		}

	}


	public static void main(String[] args) throws Exception {
		System.out.println("CommUtil "+System.currentTimeMillis());
		
		Map<String,String> argsmap = CommUtil.getArgsMap(args);
		if(argsmap==null){
			argsmap = new HashMap<String,String>();
		}
		int intv = getInt(argsmap,"a",-1);
		long longv = getLong(argsmap,"a",-1);
		System.out.println("argsmap="+argsmap);
		System.out.println("intv="+intv);
		System.out.println("longv="+longv);
		
		argsmap.put("a", "9");
	    intv = getInt(argsmap,"a",-1);
		longv = getLong(argsmap,"a",-1);
		System.out.println("argsmap="+argsmap);
		System.out.println("intv="+intv);
		System.out.println("longv="+longv);
		
		System.out.println("config.app="+getConfigString("app"));
		
		
		Date now = new Date();
		// 2018-08-31    118 7 31 
		System.out.println(now.getYear()+","+now.getMonth()+","+now.getDate()+","+now.getDay());
        // 16:41:11     16 41 11
		System.out.println(now.getHours()+","+now.getMinutes()+","+now.getSeconds());
		
		Date minDate = new Date(100,0,1);
		System.out.println(minDate);
		
		System.out.println(getSimpleDateTimeString(minDate));
		
		String str = "2018-01-02 03:04:05";
		Date date = parseDate(str,null);
		System.out.println(str);
		System.out.println(getSimpleDateTimeString(date));
		
		str = "2018-10-11 12:13:15";
	    date = parseDate(str,null);
		System.out.println(str);
		System.out.println(getSimpleDateTimeString(date));
		
		System.out.println(getUpdateTimeString("0"));
		System.out.println(getUpdateTimeString((CommConst.MIN_TIME_MS-1)+""));
		System.out.println(getUpdateTimeString((CommConst.MIN_TIME_MS+100)+""));
		System.out.println(getUpdateTimeString(System.currentTimeMillis()+""));



	}
	
	
	public static String getSimpleDateString(Date date){
		if(date==null){
			return null;
		}
		StringBuilder sb = new StringBuilder(16);
		sb.append(date.getYear()+YEAR_OFFSET);
		sb.append(LINK);
		int month = date.getMonth()+MONTH_OFFSET;
		if(month<10){
			sb.append(CommConst.ZERO);
		}
		sb.append(month);
		sb.append(LINK);
		int dd = date.getDate();
		if(dd<10){
			sb.append(CommConst.ZERO);
		}
		sb.append(dd);
		return sb.toString();
	}
	
	public static String getSimpleTimeString(Date date){
		if(date==null){
			return null;
		}
		
		StringBuilder sb = new StringBuilder(16);
		int h = date.getHours();
		if(h<10){
			sb.append(CommConst.ZERO);
		}
		sb.append(h);
		sb.append(TIME_SEP);
		int m = date.getMinutes();
		if(m<10){
			sb.append(CommConst.ZERO);
		}
		sb.append(m);
		sb.append(TIME_SEP);
		int s = date.getSeconds();
		if(s<10){
			sb.append(CommConst.ZERO);
		}
		sb.append(s);
	
		return sb.toString();	
		
	}
	
	public static String getSimpleDateTimeString(Date date){
		if(date==null){
			return null;
		}
		StringBuilder sb = new StringBuilder(32);
		sb.append(getSimpleDateString(date));
		sb.append(" ");
		sb.append(getSimpleTimeString(date));
		return sb.toString();
	}
	

	public static String getUpdateTimeString(String longstr){		
		long time = getLong(longstr,0);
		Date date = null;
		if(time<CommConst.MIN_TIME_MS){
			date = CommConst.MIN_TIME;
		}else{
			date = new Date(time);
		}
			
		return getSimpleDateString(date);
	}
	
	
	public static boolean isBlank(String str){
		return StringUtils.isBlank(str);
	}


	public static void doSleep(long time){
		try{
			if(time<=0){
				return;
			}
			Thread.sleep(time);
		}catch(Throwable e){

		}
	}


	public static byte[] readBytesFromResource(String name) throws Exception {
		InputStream is = null;
		try {
			is = CommUtil.class.getResourceAsStream(name);
			
			if(is==null){
				is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
			}
			if (is == null) {
				throw new Exception("resource not find,name=" + name);
			}
			return toBytes(is);
		} finally {
			close(is);
		}
	}

	/**
	 *
	 * @param name   /conf.properties
	 * @param charset
	 * @return
	 * @throws Exception
	 */
	public static String readFromResource(String name,String charset) throws Exception {
		byte[] bytes = readBytesFromResource(name);
		if(bytes==null || bytes.length<=0){
			return null;
		}
		if(charset==null){
			charset = UTF8;
		}
		return new String(bytes,charset);
	}

    public static byte[] readBytes(String file) throws Exception {
		InputStream is = null;
		try {
			is = new FileInputStream(new File(file));
            return toBytes(is);
		} finally {
			close(is);
		}
	}

    public static String read(String file,String charset) throws Exception {
    	byte[] bytes = readBytes(file);
		if(bytes==null || bytes.length<=0){
			return null;
		}
		if(charset==null){
			charset = UTF8;
		}
		return new String(bytes,charset);
	}

    private static byte[] toBytes(InputStream is)throws Exception{
    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
    	int tmp = 0;
    	while((tmp=is.read())!=-1){
    		bos.write(tmp);
    	}
    	return bos.toByteArray();
    }

    public static void close(Closeable obj) {
		if (obj == null) {
			return;
		}
		try {
			obj.close();
		} catch (Throwable e) {

		}
	}


    public static String getConf()throws Exception{
    	return readFromResource(CONF,null);
    }
    
    public static Map<String,String> getConfigMap()throws Exception{
    	
    	return null;
    }
    
    public static String getConfigString(String key){
    	if(key==null){
    		return null;
    	}
    	return configMap.get(key);
    }
    
    public static int getConfigInt(String key){
    	String str = getConfigString(key);
    	return getInt(str);
    }
    
    
    public static long getConfigLong(String key){
    	String str = getConfigString(key);
    	return getLong(str);
    }
    
    
    private static Map<String,String> getConfigMap_()throws Exception{
    	//Map<String,String> map = new HashMap<String,String>();
    	String lines = getConf();
    	if(StringUtils.isBlank(lines)){
    		return null;
    	}
    	String[]arr = StringUtils.split(lines,"\n");
    	
    	return getArgsMap(arr);
    }
    
    
   public static Map<String,String> getConfigMapCopy()throws Exception{
	   Map<String,String> map = new HashMap<String,String>();	   
	   map.putAll(configMap);	   
	   return map;
   }

    public static int size(List list){
    	if(list==null){
    		return -1;
    	}
    	return list.size();
    }

    public static boolean empty(List list){
    	if(list==null || list.isEmpty()){
    		return true;
    	}
    	return false;
    }


    public static String getDataString(Map<String,String> map){
    	if(map==null || map.isEmpty()){
    		return null;
    	}
    	Set<Map.Entry<String, String>> entrys = map.entrySet();
    	String key = null;
    	String value = null;
    	StringBuilder sb = new StringBuilder();
    	boolean first = true;
    	for(Map.Entry<String, String> item:entrys){
    		key = item.getKey();
    		value = item.getValue();
    		if(StringUtils.isBlank(key) || StringUtils.isBlank(value)){
    			continue;
    		}
    		key = key.trim();
    		value = value.trim();

    		if(first){
    			first = false;
    		}else{
    			sb.append(CommConst.COMM);
    		}
    		sb.append(key).append(CommConst.EQ).append(value);
    	}

    	return sb.toString();
    }

    public static Map<String,String> getDataMap(String str){
    	if(StringUtils.isBlank(str)){
    		return null;
    	}
    	String[]arr = StringUtils.split(str, CommConst.COMM);
    	//String[]arr = StringUtils.split(str, CommConst.COMM);
    	if(arr==null||arr.length<=0){
    		return null;
    	}
    	Map<String,String> map = new HashMap<String,String>();
    	for(String item:arr){
    		if(StringUtils.isBlank(item)){
    			continue;
    		}
    		buildDataValue(item,map);
    	}

    	return map;
    }

    private static void buildDataValue(String str,Map<String,String> map){
    	int pos = str.indexOf(CommConst.EQ);
    	if(pos<=0){
    		return;
    	}
    	String key = str.substring(0, pos);
    	if(StringUtils.isBlank(key)){
    		return;
    	}
    	String value = str.substring(pos+1);
    	if(StringUtils.isBlank(value)){
    		return;
    	}
    	key = key.trim();
		value = value.trim();
    	map.put(key, value);
    }


    public static BufferedReader createBufferedReader(String file,String charset)throws Exception{
    	if(StringUtils.isBlank(charset)){
    		charset = CommConst.UTF8;
    	}

    	BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),charset));

    	return br;
    }

    
    public static BufferedWriter createBufferedWriter(String file,String charset,boolean append)throws Exception{
    	if(StringUtils.isBlank(charset)){
    		charset = CommConst.UTF8;
    	}
    	
    	File f = new File(file);
    	File pf = f.getParentFile();
    	if (!pf.exists()) {
			pf.mkdirs();
		}
    	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,append),charset));

    	
    	return bw;
    }
    
    
    public static String readFirstLine(BufferedReader br,boolean ignoreBlank)throws Exception{
    	String line = null;
    	while((line=br.readLine())!=null){

    		if(ignoreBlank && StringUtils.isBlank(line)){
    			continue;
    		}

    		return line;
    	}
    	return null;
    }

	public static String readFirstLine(String file, String charset, boolean ignoreBlank) throws Exception {

		BufferedReader br = null;
		try {
			br = createBufferedReader(file, charset);
			return readFirstLine(br, ignoreBlank);
		} finally {
			close(br);
		}

	}


    public static long getLong(String str){
    	return getLong(str,0);
    }
    

    public static int getInt(String str){
    	return getInt(str,0);
    }
    
    public static long getLong(String str,long def){
    	try{
    		return Long.parseLong(str);
    	}catch(Throwable e){
    		return def;
    	}
    }
    

    public static int getInt(String str,int def){
    	try{
    		return Integer.parseInt(str);
    	}catch(Throwable e){
    		return def;
    	}
    }

    
    public static double getDouble(String str,int def){
    	try{
    		return Double.parseDouble(str);
    	}catch(Throwable e){
    		return def;
    	}
    }





	public static String getDateString(Date date, String format) {
		if (date == null) {
			return null;
		}
		if (StringUtils.isBlank(format)) {
			format = DATE_FORMAT;
		}
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.format(date);
		} catch (Throwable e) {
			return date.toString();
		}
	}
	
	public static Date parseDate(String str, String format) {
		if(StringUtils.isBlank(str)){
			return null;
		}
		if (StringUtils.isBlank(format)) {
			format = DATE_FORMAT;
		}
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.parse(str);
		} catch (Throwable e) {
			return null;
		}
	}

	public static String getDateString(Date date) {
		return getDateString(date, null);
	}

	public static String getNowDateString() {
		return getDateString(new Date(), null);
	}
	
	public static Map<String,String> getArgsMap(String[]args){
		if(args==null || args.length<=0){
			return null;
		}
		int pos = 0;
		String key = null;
		String value = null;
		Map<String,String> map = new HashMap<String,String>();
		for(String item:args){
			if(StringUtils.isBlank(item)){
				continue;
			}
			item = item.trim();
			pos = item.indexOf(CommConst.EQ);
			if(pos<=0){
				continue;
			}
			key = item.substring(0, pos);
			value = item.substring(pos+1);
			if(StringUtils.isBlank(key) || StringUtils.isBlank(value)){
				continue;
			}
			key = key.trim();
			value = value.trim();
			map.put(key, value);
	
		}
		
		return map;
	}
	
	public static Map<String,String> getArgsMap(String str){
		
		return getArgsMap(StringUtils.split(str, CommConst.BLANK));
	}
	

	public static int getInt(Map<String,String> map,String key){		
		return getInt(map,key,0);
	}
	
	public static long getLong(Map<String,String> map,String key){		
		return getLong(map,key,0);
	}
	
	

	public static int getInt(Map<String,String> map,String key,int def){		
		if(map==null || StringUtils.isBlank(key)){
			return def;
		}
		return getInt(map.get(key),def);
	}
	
	public static long getLong(Map<String,String> map,String key,long def){		
		if(map==null || StringUtils.isBlank(key)){
			return def;
		}
		return getLong(map.get(key),def);
	}
	
	public static String get(Map<String,String> map,String key){		
		if(map==null || StringUtils.isBlank(key)){
			return null;
		}
		return map.get(key);
	}
	
    public static int strlen(Object o){
    	if(o==null){
    		return -1;
    	}
    	return o.toString().length();
    }
    
	public static void write(String file, String charset, String str) throws Exception {
		if (StringUtils.isBlank(file)) {
			return;
		}
		if (StringUtils.isBlank(str)) {
			return;
		}
		BufferedWriter bw = null;

		try {
			bw = createBufferedWriter(file, charset, false);
			bw.write(str);
		} finally {
			close(bw);
		}
	}
	
	
	public static void write(String file, String str) throws Exception {
		write(file,null,str);
	}

	
	//
	/**
	 * 根据开始和结束字符串提取 子串
	 * @param str
	 * @param start
	 * @param end
	 * @return
	 */
	public static String getSubString(String str,String start,String end){
		if(str==null || str.isEmpty()){
			return null;
		}
		if(start==null || start.isEmpty()){
			return null;
		}
		if(end==null || end.isEmpty()){
			return null;
		}
		
		int startIndex = str.indexOf(start);
		if(startIndex<0){
			return null;
		}
		// a='12345';
		
		startIndex = startIndex+start.length();
		int endIndex = str.indexOf(end,startIndex);
		if(endIndex <= startIndex){
			return null;
		}
		
		return str.substring(startIndex, endIndex);
	}
	
}
